import express from 'express';
import multer from 'multer';
import { fileURLToPath } from 'url';
import path from 'path';
import cors from 'cors';
import request from 'request';
import fs from 'fs';
import { WebSocketServer, WebSocket } from 'ws';

const wss = new WebSocketServer({ port: 3001 });
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();

// 设置跨域访问
app.use(cors());

const VITE_SECRET = "2b402981b0efb3f0aa199ad558698ec5"

const responseData = {
  imageActionName: "image",
  imageFieldName: "file",
  imageMaxSize: 10485760,
  imageAllowFiles: [".jpg", ".png", ".jpeg"],
  imageCompressEnable: true,
  imageCompressBorder: 5000,
  imageInsertAlign: "none",
  imageUrlPrefix: "",
  scrawlActionName: "scrawl",
  scrawlFieldName: "file",
  scrawlMaxSize: 10485760,
  scrawlUrlPrefix: "",
  scrawlInsertAlign: "none",
  snapscreenActionName: "snap",
  snapscreenUrlPrefix: "",
  snapscreenInsertAlign: "none",
  catcherLocalDomain: ["127.0.0.1", "localhost"],
  catcherActionName: "catch",
  catcherFieldName: "source",
  catcherUrlPrefix: "",
  catcherMaxSize: 10485760,
  catcherAllowFiles: [".jpg", ".png", ".jpeg"],
  videoActionName: "video",
  videoFieldName: "file",
  videoUrlPrefix: "",
  videoMaxSize: 104857600,
  videoAllowFiles: [".mp4"],
  audioActionName: "audio",
  audioFieldName: "file",
  audioUrlPrefix: "",
  audioMaxSize: 104857600,
  audioAllowFiles: [".mp3"],
  fileActionName: "file",
  fileFieldName: "file",
  fileUrlPrefix: "",
  fileMaxSize: 104857600,
  fileAllowFiles: [".zip", ".pdf", ".doc"],
  imageManagerActionName: "listImage",
  imageManagerListSize: 20,
  imageManagerUrlPrefix: "",
  imageManagerInsertAlign: "none",
  imageManagerAllowFiles: [".jpg", ".png", ".jpeg"],
  fileManagerActionName: "listFile",
  fileManagerUrlPrefix: "",
  fileManagerListSize: 20,
  fileManagerAllowFiles: [".zip", ".pdf", ".doc"],
  _all: {
    POST: [],
    FILES: [],
    GET: {
      action: "config",
      encode: "utf-8",
      noCache: "1715934436686",
    },
  },
};
// 设置用于解析请求体的中间件
app.use(express.json()); // 解析 application/json
app.use(express.urlencoded({ extended: true })); // 解析 application/x-www-form-urlencoded
// 设置静态文件目录
app.use(express.static(path.join(__dirname, 'public')));

const uploadsPath = path.join(__dirname, 'public', 'uploads');
const xiumiPath = path.join(__dirname, 'public', 'uploads' ,'xiumi');
const editorPath = path.join(__dirname, 'public', 'uploads', 'editor');

// 检查uploads文件夹是否存在
if (!fs.existsSync(uploadsPath)) {
  // 创建uploads文件夹
  fs.mkdirSync(uploadsPath);
}

// 检查秀米文件夹是否存在
if (!fs.existsSync(xiumiPath)) {
  // 创建秀米文件夹
  fs.mkdirSync(xiumiPath);
}

// 检查editor文件夹是否存在
if (!fs.existsSync(editorPath)) {
  // 创建editor文件夹
  fs.mkdirSync(editorPath);
}

// 配置上传文件的存储位置和命名
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        let imgPath = path.join(__dirname, '/public/uploads/editor');
        if(req.query.partner_user_id) {
          const userPath = path.join(__dirname, '/public/uploads/xiumi', req.query.partner_user_id);
          imgPath = path.join(__dirname, '/public/uploads/xiumi', req.query.partner_user_id, '/image');
          // 创建用户文件夹
          if (!fs.existsSync(userPath)) {
            // 创建htmls文件夹
            fs.mkdirSync(userPath);
          }
          // 创建用户图片文件夹
          if (!fs.existsSync(imgPath)) {
            // 创建htmls文件夹
            fs.mkdirSync(imgPath);
          }
        }
        cb(null, imgPath);
    },
    filename: function (req, file, cb) {
        // const lastDotIndex = file.originalname.lastIndexOf('.');
        // const fileExtension = lastDotIndex !== -1 ? file.originalname.substring(lastDotIndex + 1).toLowerCase() : '';
        // file.fieldname + '-' + Date.now() + '.jpg'
        cb(null, file.originalname);
    }
});

const upload = multer({ storage: storage });
// 处理ueditor初始化的接口
app.get("/server", function (req, res, next) {
    const { source, action, callback } = req.query;
    if (action === 'catch') {
      const sourceUrl = source[0]; // 获取远程图片的 URL
      // const slashBeforeQuestionMarkIndex = sourceUrl.lastIndexOf('/', sourceUrl.indexOf('?')); // 找到问号前一个斜杠的索引
      // const questionMarkIndex = sourceUrl.indexOf('?'); // 找到问号的索引
      // let fileName = sourceUrl.substring(slashBeforeQuestionMarkIndex + 1, questionMarkIndex); // 使用 substring 方法提取问号前一个斜杠到问号之间的部分作为文件名
      // if(questionMarkIndex === -1) fileName = sourceUrl.substring(sourceUrl.lastIndexOf('/') + 1); // 获取图片文件名
      const fileName = responseData.fileFieldName + '-' + Date.now() + '.jpg';
      const imagePath = path.join(__dirname, '/public/uploads/editor/') + fileName; // 本地文件保存路径
      // 使用 request 模块下载远程图片到本地
      request(sourceUrl)
          .pipe(fs.createWriteStream(imagePath))
          .on('close', () => {
              console.log('Image downloaded to:', imagePath);
              // 响应给前端 JSON 数据，包含本地图片路径
              res.jsonp({ state: 'SUCCESS', list: [
                {
                  state: 'SUCCESS',
                  url: `${req.protocol}://${req.get('host')}/uploads/editor/${fileName}`
                }
              ] });
          });

    }else {
      // 检查请求中是否包含 callback 参数
      if (callback) {
          // 返回 JSONP 格式的数据
          res.jsonp(responseData);
      } else {
          // 直接返回 JSON 数据
          res.json(responseData);
      }
    }
});

// 处理图片上传的接口
app.post('/server', upload.single('file'), function (req, res, next) {
    if (req.query.action === 'scrawl') {
        // 如果是涂鸦上传
        const imageData = req.body.file; // 获取涂鸦数据
        const fileName = responseData.scrawlFieldName + '-' + Date.now() + '.png'; // 生成文件名
        const imagePath = path.join(__dirname, '/public/uploads/editor/') + fileName; // 本地文件保存路径
        const filePath = `${req.protocol}://${req.get('host')}/uploads/editor/${fileName}`;
        // 将涂鸦数据写入文件
        fs.writeFile(imagePath, imageData, 'base64', function (err) {
            // 返回给前端本地图片路径
            res.json({
              state: 'SUCCESS',
              url: filePath
            });
        });
    } else {
        // 假设图片上传成功，返回图片的保存路径
        const filePath = `${req.protocol}://${req.get('host')}/uploads/editor/${req.file.filename}`;
        res.json({
            state: 'SUCCESS',
            url: filePath
        });
    }
});

// 处理秀米图片上传的接口
app.post('/upload', function (req, res, next) {
  // 调用 upload.single('img-upload') 中间件处理文件上传
  upload.single('img-upload')(req, res, function (err) {
    if (err) {
      return res.json({
        code: 400,
        msg: "文件上传失败"
      });
    }
    const secret = req.headers.authorization?.split(' ');
    if(secret?.length === 2 && secret[0] === 'secret' && secret[1] === VITE_SECRET) {
      // 假设图片上传成功，返回图片的保存路径
      const filePath = `${req.protocol}://${req.get('host')}/uploads/xiumi/${req.query.partner_user_id}/image/${req.file.filename}`
      res.json({
        code: 0,
        msg: "success",
        data: {
          url: filePath
      }});
    }else {
      res.json({
        code: 400,
        msg: "secret验证失败"
      });
    }
  });
});

// 接口，将HTML数据写入文件
app.post('/save-html', (req, res) => {
  const htmlData = req.body.articles?.[0]; // 获取HTML数据
  const fileName = 'saved-html-' + Date.now() + '.html'; // 生成文件名
  const userPath = path.join(__dirname, '/public/uploads/xiumi', req.query.partner_user_id);
  const htmlPath = path.join(__dirname, '/public/uploads/xiumi', req.query.partner_user_id, 'html/');
  const filePath = htmlPath + fileName; // 文件保存路径
  const secret = req.headers.authorization?.split(' ');
  // 检查用户文件夹是否存在
  if (!fs.existsSync(userPath)) {
    // 创建用户文件夹
    fs.mkdirSync(userPath);
  }
  // 检查用户html文件夹是否存在
  if (!fs.existsSync(htmlPath)) {
    // 创建用户html文件夹
    fs.mkdirSync(htmlPath);
  }
  if(secret?.length === 2 && secret[0] === 'secret' && secret[1] === VITE_SECRET) {
    fs.writeFile(filePath, htmlData?.description, 'utf8', function (err) {
      if (err) {
        res.json({ 
          code: 400,
          msg: "图文HTML存储失败"
        });
      } else {
        // 向前端发送消息
        wss.clients.forEach(client => {
          if (client.readyState === WebSocket.OPEN) {
              client.send(JSON.stringify({
                type: 'html',
                content: htmlData?.description
              }));
          }
        });
        res.json({ 
          code: 0,
          msg: 'success',
          // data: {
          //   url: `${req.protocol}://${req.get('host')}/uploads/xiumi/${req.query.partner_user_id}/html/${fileName}`
          // }
         }); // 返回文件路径
      }
    });
  }else {
    res.json({
      code: 400,
      msg: "secret验证失败"
    });
  }
});


// 后端接收秀米通知消息的路由处理
app.post('/api/notifications', (req, res) => {
  const secret = req.headers.authorization?.split(' ');
  // 处理接收到的秀米通知消息
  const notificationData = req.body; // 假设秀米通知消息以JSON格式发送且可以通过req.body接收
  const notice = {
    bind: "绑定成功",
    unbind: "解绑成功",
    err_html: "HTML存储失败",
    err_image: "图片存储失败",
    secret_reset: 'secret已重置'
  }
  if(secret?.length === 2 && secret[0] === 'secret' && secret[1] === VITE_SECRET) {
    // 处理业务逻辑
    // 向前端发送消息
    wss.clients.forEach(client => {
      if (client.readyState === WebSocket.OPEN) {
          client.send(JSON.stringify(notificationData));
      }
    });
    res.json({
      code: 0,
      msg: notice[notificationData?.type]
    });
  }else {
    res.json({
      code: 400,
      msg: "secret验证失败"
    });
  }
});

wss.on('connection', (ws) => {
  console.log('客户端连接已开启');

  ws.on('message', (message) => {
    console.log('收到: %s', message);
    // 发送消息给客户端
    ws.send('收到服务端消息: ' + message);
  });

  ws.on('close', () => {
    console.log('客户端连接已关闭');
  });
});

// 创建HTTP服务器
const server = app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

server.on('upgrade', (request, socket, head) => {
  wss.handleUpgrade(request, socket, head, (ws) => {
      wss.emit('connection', ws, request);
  });
});